﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NetworkATMForm
{
    public delegate void WrittenMethod(ArgList args);
    public class ComParser
    {
        ArgList args = new ArgList();
        List<ComFormat> coms = new List<ComFormat>();

        public void AddFormat(string mask, WrittenMethod method) { coms.Add(new ComFormat(mask, method)); }
        public Boolean Match(string toCheck, string toComp)
        {
            string checkRem, compRem, compBit;
            int obi, cbi, biti;
            checkRem = toCheck; compRem = toComp;

            obi = compRem.IndexOf('['); cbi = compRem.IndexOf(']');
            while (compRem != "")
            {
                obi = compRem.IndexOf('['); cbi = compRem.IndexOf(']');
                if (obi > -1 && cbi > -1)
                {
                    compBit = compRem.Substring(0, obi);
                    compRem = compRem.Substring(Math.Min(compRem.Length, cbi + 1));
                }
                else
                {
                    compBit = compRem;
                    compRem = "";
                }
                biti = checkRem.IndexOf(compBit);
                if (biti == -1)
                    return false;
                checkRem = checkRem.Substring(biti + compBit.Length);
            }
            return true;
        }

        public Boolean Execute(string toExecute)
        {
            foreach (ComFormat format in coms)
            {
                if (ExecuteSingle(toExecute, format.gMask(), format.gMethod())) return true;
            }
            return false;
        }
        public Boolean ExecuteSingle(string toExecute, string mask, WrittenMethod called)
        {
            args.Clear();
            string exRem, maskRem, maskBit;
            string prevName, curName;
            int obi, cbi, biti;
            bool first = true;
            exRem = toExecute; maskRem = mask;

            prevName = "";
            curName = "";

            biti = 0;

            obi = maskRem.IndexOf('['); cbi = maskRem.IndexOf(']');
            while (maskRem != "")
            {
                obi = maskRem.IndexOf('['); cbi = maskRem.IndexOf(']');
                if (obi > -1 && cbi > -1)
                {
                    maskBit = maskRem.Substring(0, obi);
                    curName = maskRem.Substring(obi + 1, cbi - (obi + 1));
                    maskRem = maskRem.Substring(Math.Min(maskRem.Length, cbi + 1));
                }
                else
                {
                    maskBit = maskRem;
                    curName = null;
                    maskRem = "";
                }
                biti = exRem.IndexOf(maskBit);
                if (biti == -1) return false;
                if (first && biti != 0) return false;
                if (!first) args.Add(prevName, exRem.Substring(0, biti).Trim());
                exRem = exRem.Substring(biti + maskBit.Length);

                first = false;
                prevName = curName;
            }
            if (prevName != null) args.Add(prevName, exRem);

            called(args);

            return true;
        }
    }
    public class ArgBit
    {
        public string name;
        public string value;
        public ArgBit(string newName, string newValue)
        {
            name = newName;
            value = newValue;
        }
    }
    public class ArgList
    {
        List<ArgBit> content = new List<ArgBit>();
        public void Clear()
        {
            content.Clear();
        }
        public void Add(string name, string value)
        {
            content.Add(new ArgBit(name, value));
        }
        public string Get(string key)
        {
            foreach (ArgBit arg in content)
            {
                if (arg.name == key)
                    return arg.value;
            }
            return null;
        }
    }
    public class ComFormat
    {
        string mask;
        WrittenMethod method;
        public ComFormat(string newMask, WrittenMethod newMethod)
        {
            mask = newMask;
            method = newMethod;
        }
        public string gMask() { return mask; }
        public WrittenMethod gMethod() { return method; }
    }

//KLASA AGENTA WĘZŁA SIECIOWEGO

}
